package org.springframework.boot.netty.argumentResolver;

import io.netty.handler.codec.http.FullHttpRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.netty.annotation.RequestParam;
import org.springframework.boot.netty.exception.ConvertException;
import org.springframework.boot.netty.listener.Message;
import org.springframework.boot.netty.support.HttpParamParser;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * Author: huoxingzhi
 * Date: 2020/12/16
 * Email: hxz_798561819@163.com
 */
public class RequestParamMethodArgumentResolver extends HandlerMethodArgumentResolverAdapter {

    @Override
    public boolean supportsParameter(Class<?> receiveClass,MethodParameter methodParameter) {
        RequestParam requestParam = methodParameter.getParameter().getAnnotation(RequestParam.class);
        return !ObjectUtils.isEmpty(requestParam);
    }

    @Override
    public Object resolveArgument(Message message, MethodParameter methodParameter) throws ConvertException {
        //BeanUtils.isSimpleValueType()
        RequestParam requestParam = methodParameter.getParameter().getAnnotation(RequestParam.class);
        String value = requestParam.value();
        if(!StringUtils.hasLength(value)){
            value = methodParameter.getParameter().getName();
        }
        String paramKey = value;
        FullHttpRequest httpRequest = (FullHttpRequest)message.getContent();
        Map<String, Object> parseParams = HttpParamParser.parseParams(httpRequest);

        if(null==parseParams){
            throw new ConvertException(getClass()+" can not parse FullHttpRequest");
        }

        return ObjectUtils.isEmpty(parseParams.get(paramKey)) ? "" : parseParams.get(paramKey);

    }


    @Override
    public Object resolveAndConvertArgument(Message message, MethodParameter methodParameter) {

        Object argument = resolveArgument(message, methodParameter);
        if(this.conversionService.canConvert(argument.getClass(),methodParameter.getParameter().getType())){
            return this.conversionService.convert(argument,methodParameter.getParameter().getType());
        }
        return argument;
    }
}
